package com.qc31.baselib.net

import com.qc31.baselib.net.errorhandler.HttpLoggingInterceptor
import com.qc31.baselib.net.errorhandler.SingleHttpErrorHandler
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.SingleTransformer
import io.reactivex.rxjava3.functions.Function
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.util.concurrent.TimeUnit

abstract class NetWorkApi : IBaseUrl {
    private val retrofitHashMap: HashMap<String, Retrofit> = HashMap()
    private val retrofitMap: HashMap<String, Retrofit> = HashMap()
    private lateinit var mBaseUrl: String
    private var mOkHttpClient: OkHttpClient? = null
    private var isDebug = true
    //是否开启Https请求
//    private var isHttps = false

    fun init(isDebug: Boolean) {
        this.isDebug = isDebug
        mBaseUrl = if (isDebug) {
            testUrl()
        } else {
            formalUrl()
        }
    }

    fun changeUrl() {
        mBaseUrl = if (isDebug) {
            testUrl()
        } else {
            formalUrl()
        }
        retrofitMap.clear()
        retrofitHashMap.clear()
    }

    protected fun <T> getRetrofit(clazz: Class<T>, url: String = mBaseUrl): Retrofit {
        if (retrofitMap[url + clazz.name] != null)
            return retrofitMap[url + clazz.name]!!
        val retrofit = Retrofit.Builder().apply {
            baseUrl(url)
            client(getOkHttpClient())
            addConverterFactory(ScalarsConverterFactory.create())
            addConverterFactory(GsonConverterFactory.create())
            addCallAdapterFactory(RxJava3CallAdapterFactory.create())
        }.build()

        retrofitMap[url + clazz.name] = retrofit
        return retrofit
    }

    /**
     * 无公共参数 无Gson转换
     */
    protected fun <T> getRetrofitNoParams(clazz: Class<T>, url: String = mBaseUrl): Retrofit {
        if (retrofitHashMap[url + clazz.name] != null)
            return retrofitHashMap[url + clazz.name]!!
        val retrofit = Retrofit.Builder().apply {
            baseUrl(url)
            client(getHttpClient())
            addConverterFactory(ScalarsConverterFactory.create())
            if (url == mBaseUrl) {
                addConverterFactory(GsonConverterFactory.create())
            }
            addCallAdapterFactory(RxJava3CallAdapterFactory.create())
        }.build()
        retrofitHashMap[url + clazz.name] = retrofit
        return retrofit
    }

    /**
     * 无公共参数 无Gson转换
     */
    protected fun <T> getRetrofitParams(clazz: Class<T>, url: String): Retrofit {
        if (retrofitHashMap[url + clazz.name] != null)
            return retrofitHashMap[url + clazz.name]!!
        val retrofit = Retrofit.Builder().apply {
            baseUrl(url)
            client(getHttpClient())
            addConverterFactory(ScalarsConverterFactory.create())
            addConverterFactory(GsonConverterFactory.create())
            addCallAdapterFactory(RxJava3CallAdapterFactory.create())
        }.build()
        retrofitHashMap[url + clazz.name] = retrofit
        return retrofit
    }


    private fun getOkHttpClient(): OkHttpClient {
        if (mOkHttpClient == null) {
            mOkHttpClient = OkHttpClient.Builder().apply {
                getInterceptor()?.let {
                    addInterceptor(it)
                }
                if (isDebug) {
                    addInterceptor(HttpLoggingInterceptor().apply {
                        level = HttpLoggingInterceptor.Level.BODY
                    })
                }
//                if (isHttps){
//                    val sslParams=HttpsUtil.getSslSocketFactory()
//                    sslSocketFactory(sslParams.sSLSocketFactory!!,sslParams.trustManager!!)
//                }
                connectTimeout(30, TimeUnit.SECONDS)//设置连接超时时间
                readTimeout(30, TimeUnit.SECONDS)//设置读取超时时间
                writeTimeout(30, TimeUnit.SECONDS)//设置写数据超时时间

            }.build()
        }
        return mOkHttpClient!!
    }


    private fun getHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            if (isDebug) {
                addInterceptor(HttpLoggingInterceptor().apply {
                    level = HttpLoggingInterceptor.Level.BODY
                })
            }
//            if (isHttps){
//                val sslParams=HttpsUtil.getSslSocketFactory()
//                sslSocketFactory(sslParams.sSLSocketFactory!!,sslParams.trustManager!!)
//            }
            connectTimeout(30, TimeUnit.SECONDS)//设置连接超时时间
            readTimeout(30, TimeUnit.SECONDS)//设置读取超时时间
            writeTimeout(30, TimeUnit.SECONDS)//设置写数据超时时间
        }.build()
    }


    fun <T> applySingleSchedulers(): SingleTransformer<T, T> {
        return SingleTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io())
                .map(getAppErrorHandler())
                .observeOn(AndroidSchedulers.mainThread())
                .onErrorResumeNext(SingleHttpErrorHandler<T>())
        }
    }


    fun <T> applyNoMapSingleSchedulers(): SingleTransformer<T, T> {
        return SingleTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .onErrorResumeNext(SingleHttpErrorHandler<T>())
        }
    }

    abstract fun <T> getAppErrorHandler(): Function<T, T>

    abstract fun getInterceptor(): Interceptor?


}